home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / asa / user.c < prev    next >
C/C++ Source or Header  |  1994-10-23  |  57KB  |  1,967 lines

  1. /***********************************************************************
  2. * Lester Ingber (copyright) (c)
  3. * See COPYING License in this directory
  4. * Date   1 Jan 93
  5. ***********************************************************************/
  6.  
  7. #define USER_ID \
  8. "/* $Id: user.c,v 4.2 1994/10/23 23:35:13 ingber Exp ingber $ */"
  9.  
  10. #include "user.h"
  11.  
  12. #if SELF_OPTIMIZE
  13. #else
  14.  
  15. /***********************************************************************
  16. * main
  17. *    This is a sample calling program to optimize using ASA
  18. ***********************************************************************/
  19. #if HAVE_ANSI
  20. #if ASA_LIB
  21. int
  22. asa_main ()
  23. #else
  24. int
  25. main (int argc, char **argv)
  26. #endif
  27. #else
  28. #if ASA_LIB
  29. int
  30. asa_main ()
  31. #else
  32. int
  33. main (argc, argv)
  34.      int argc;
  35.      char **argv;
  36. #endif
  37. #endif
  38. {
  39.   int *exit_code;
  40. #if ASA_LIB
  41. #else
  42.   int compile_cnt;
  43. #endif
  44. #if ASA_SAMPLE
  45. #if ASA_TEMPLATE
  46.   FILE *ptr_asa;
  47. #endif
  48. #endif
  49.  
  50.   /* pointer to array storage for asa arguments */
  51.   double *parameter_lower_bound, *parameter_upper_bound, *cost_parameters,
  52.    *cost_tangents, *cost_curvature;
  53.   double cost_value;
  54.  
  55.   /* the number of parameters to optimize */
  56.   ALLOC_INT *parameter_dimension;
  57.  
  58.   /* pointer to array storage for parameter type flags */
  59.   int *parameter_int_real;
  60.  
  61.   /* valid flag for cost function */
  62.   int *cost_flag;
  63.  
  64.   USER_DEFINES *USER_OPTIONS;
  65.  
  66. #if OPTIONS_FILE
  67.   FILE *ptr_options;
  68.   char read_option[80];
  69.   int read_int;
  70.   LONG_INT read_long;
  71.   double read_double;
  72. #endif
  73.  
  74. #if ASA_TEMPLATE
  75. #if USER_ASA_OUT
  76.   int n_asa, n_trajectory, index;
  77. #if HAVE_ANSI
  78.   char asa_file[8] = "asa_x_y";
  79. #else
  80.   char asa_file[8];
  81.   asa_file[0] = asa_file[2] = 'a';
  82.   asa_file[1] = 's';
  83.   asa_file[3] = asa_file[5] = '_';
  84.   asa_file[4] = 'x';
  85.   asa_file[6] = 'y';
  86.   asa_file[7] = '\0';
  87. #endif /* HAVE_ANSI */
  88. #endif /* USER_ASA_OUT */
  89. #endif /* ASA_TEMPLATE */
  90.  
  91.   /* open the output file */
  92.   ptr_out = fopen ("user_out", "w");
  93.   /* use this instead if you want output to stdout */
  94. #if FALSE
  95.   ptr_out = stdout;
  96. #endif
  97.   fprintf (ptr_out, "%s\n\n", USER_ID);
  98.  
  99. #if ASA_LIB
  100. #else
  101.   /* print out compile options set by user in Makefile */
  102.   if (argc > 1)
  103.     {
  104.       fprintf (ptr_out, "CC = %s\n", argv[1]);
  105.       for (compile_cnt = 2; compile_cnt < argc; ++compile_cnt)
  106.     {
  107.       fprintf (ptr_out, "\t%s\n", argv[compile_cnt]);
  108.     }
  109.       fprintf (ptr_out, "\n");
  110.     }
  111. #endif
  112. #if TIME_CALC
  113.   /* print starting time */
  114.   print_time ("start", ptr_out);
  115. #endif
  116.   fflush (ptr_out);
  117.  
  118. #if OPTIONAL_DATA
  119.   /* Set memory to that required for use. */
  120.   if ((USER_OPTIONS->asa_data =
  121.        (double *) calloc (2, sizeof (double))) == NULL)
  122.       exit (9);
  123.   /* Use asa_data[0] as flag, e.g., if used with SELF_OPTIMIZE. */
  124.   USER_OPTIONS->asa_data[0] = 1.0;
  125. #endif
  126.  
  127.   initialize_rng ();
  128.  
  129.   /* Initialize the users parameters, allocating space, etc.
  130.      Note that the default is to have asa generate the initial
  131.      cost_parameters that satisfy the user's constraints. */
  132.  
  133.   if ((parameter_dimension =
  134.        (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL)
  135.     exit (9);
  136.   if ((exit_code = (int *) calloc (1, sizeof (int))) == NULL)
  137.       exit (9);
  138.   if ((cost_flag = (int *) calloc (1, sizeof (int))) == NULL)
  139.       exit (9);
  140.  
  141. #if SELF_OPTIMIZE
  142. #else
  143.  
  144.   if ((USER_OPTIONS =
  145.        (USER_DEFINES *) calloc (1, sizeof (USER_DEFINES))) == NULL)
  146.     exit (9);
  147.  
  148. #if OPTIONS_FILE
  149.   ptr_options = fopen ("asa_opt", "r");
  150.  
  151. #if INT_LONG
  152.   fscanf (ptr_options, "%s", read_option);
  153.   fscanf (ptr_options, "%ld", &read_long);
  154.   USER_OPTIONS->LIMIT_ACCEPTANCES = read_long;
  155.   fscanf (ptr_options, "%s", read_option);
  156.   fscanf (ptr_options, "%ld", &read_long);
  157.   USER_OPTIONS->LIMIT_GENERATED = read_long;
  158. #else
  159.   fscanf (ptr_options, "%s", read_option);
  160.   fscanf (ptr_options, "%d", &read_int);
  161.   USER_OPTIONS->LIMIT_ACCEPTANCES = read_int;
  162.   fscanf (ptr_options, "%s", read_option);
  163.   fscanf (ptr_options, "%d", &read_int);
  164.   USER_OPTIONS->LIMIT_GENERATED = read_int;
  165. #endif
  166.   fscanf (ptr_options, "%s", read_option);
  167.   fscanf (ptr_options, "%d", &read_int);
  168.   USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = read_int;
  169.   fscanf (ptr_options, "%s", read_option);
  170.   fscanf (ptr_options, "%lf", &read_double);
  171.   USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = read_double;
  172.  
  173.   fscanf (ptr_options, "%s", read_option);
  174.   fscanf (ptr_options, "%lf", &read_double);
  175.   USER_OPTIONS->COST_PRECISION = read_double;
  176.   fscanf (ptr_options, "%s", read_option);
  177.   fscanf (ptr_options, "%d", &read_int);
  178.   USER_OPTIONS->MAXIMUM_COST_REPEAT = read_int;
  179.   fscanf (ptr_options, "%s", read_option);
  180.   fscanf (ptr_options, "%d", &read_int);
  181.   USER_OPTIONS->NUMBER_COST_SAMPLES = read_int;
  182.   fscanf (ptr_options, "%s", read_option);
  183.   fscanf (ptr_options, "%lf", &read_double);
  184.   USER_OPTIONS->TEMPERATURE_RATIO_SCALE = read_double;
  185.   fscanf (ptr_options, "%s", read_option);
  186.   fscanf (ptr_options, "%lf", &read_double);
  187.   USER_OPTIONS->COST_PARAMETER_SCALE = read_double;
  188.   fscanf (ptr_options, "%s", read_option);
  189.   fscanf (ptr_options, "%lf", &read_double);
  190.   USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = read_double;
  191.   fscanf (ptr_options, "%s", read_option);
  192.   fscanf (ptr_options, "%d", &read_int);
  193.   USER_OPTIONS->USER_INITIAL_COST_TEMP = read_int;
  194.  
  195.   fscanf (ptr_options, "%s", read_option);
  196.   fscanf (ptr_options, "%d", &read_int);
  197.   USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = read_int;
  198.   fscanf (ptr_options, "%s", read_option);
  199.   fscanf (ptr_options, "%d", &read_int);
  200.   USER_OPTIONS->USER_INITIAL_PARAMETERS = read_int;
  201. #if INT_ALLOC
  202.   fscanf (ptr_options, "%s", read_option);
  203.   fscanf (ptr_options, "%d", &read_int);
  204.   USER_OPTIONS->SEQUENTIAL_PARAMETERS = read_int;
  205. #else
  206. #if INT_LONG
  207.   fscanf (ptr_options, "%s", read_option);
  208.   fscanf (ptr_options, "%ld", &read_long);
  209.   USER_OPTIONS->SEQUENTIAL_PARAMETERS = read_long;
  210. #else
  211.   fscanf (ptr_options, "%s", read_option);
  212.   fscanf (ptr_options, "%d", &read_int);
  213.   USER_OPTIONS->SEQUENTIAL_PARAMETERS = read_int;
  214. #endif
  215. #endif
  216.   fscanf (ptr_options, "%s", read_option);
  217.   fscanf (ptr_options, "%lf", &read_double);
  218.   USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = read_double;
  219.   fscanf (ptr_options, "%s", read_option);
  220.   fscanf (ptr_options, "%d", &read_int);
  221.   USER_OPTIONS->RATIO_TEMPERATURE_SCALES = read_int;
  222.   fscanf (ptr_options, "%s", read_option);
  223.   fscanf (ptr_options, "%d", &read_int);
  224.   USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = read_int;
  225.  
  226.   fscanf (ptr_options, "%s", read_option);
  227.   fscanf (ptr_options, "%d", &read_int);
  228.   USER_OPTIONS->TESTING_FREQUENCY_MODULUS = read_int;
  229.   fscanf (ptr_options, "%s", read_option);
  230.   fscanf (ptr_options, "%d", &read_int);
  231.   USER_OPTIONS->ACTIVATE_REANNEAL = read_int;
  232.   fscanf (ptr_options, "%s", read_option);
  233.   fscanf (ptr_options, "%lf", &read_double);
  234.   USER_OPTIONS->REANNEAL_RESCALE = read_double;
  235.   fscanf (ptr_options, "%s", read_option);
  236. #if INT_LONG
  237.   fscanf (ptr_options, "%ld", &read_long);
  238. #else
  239.   fscanf (ptr_options, "%d", &read_long);
  240. #endif
  241.   USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = read_long;
  242.  
  243.   fscanf (ptr_options, "%s", read_option);
  244.   fscanf (ptr_options, "%lf", &read_double);
  245.   USER_OPTIONS->DELTA_X = read_double;
  246.   fscanf (ptr_options, "%s", read_option);
  247.   fscanf (ptr_options, "%d", &read_int);
  248.   USER_OPTIONS->DELTA_PARAMETERS = read_int;
  249.   fscanf (ptr_options, "%s", read_option);
  250.   fscanf (ptr_options, "%d", &read_int);
  251.   USER_OPTIONS->USER_TANGENTS = read_int;
  252.   fscanf (ptr_options, "%s", read_option);
  253.   fscanf (ptr_options, "%d", &read_int);
  254.   USER_OPTIONS->CURVATURE_0 = read_int;
  255.  
  256.   fscanf (ptr_options, "%s", read_option);
  257.   fscanf (ptr_options, "%d", &read_int);
  258.   USER_OPTIONS->QUENCH_PARAMETERS = read_int;
  259.   fscanf (ptr_options, "%s", read_option);
  260.   fscanf (ptr_options, "%d", &read_int);
  261.   USER_OPTIONS->QUENCH_COST = read_int;
  262.   fclose (ptr_options);
  263. #else /* OPTIONS_FILE */
  264.   /* USER_OPTIONS->LIMIT_ACCEPTANCES = 10000; */
  265.   USER_OPTIONS->LIMIT_ACCEPTANCES = 1000;
  266.   USER_OPTIONS->LIMIT_GENERATED = 99999;
  267.   USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = 1000;
  268.   /* USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = 1.0E-6; */
  269.   USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = 1.0E-4;
  270.  
  271.   USER_OPTIONS->COST_PRECISION = 1.0E-18;
  272.   USER_OPTIONS->MAXIMUM_COST_REPEAT = 5;
  273.   USER_OPTIONS->NUMBER_COST_SAMPLES = 5;
  274.   USER_OPTIONS->TEMPERATURE_RATIO_SCALE = 1.0E-5;
  275.   USER_OPTIONS->COST_PARAMETER_SCALE = 1.0;
  276.   USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = 100.0;
  277.   USER_OPTIONS->USER_INITIAL_COST_TEMP = FALSE;
  278.  
  279.   USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = FALSE;
  280.   USER_OPTIONS->USER_INITIAL_PARAMETERS = FALSE;
  281.   USER_OPTIONS->SEQUENTIAL_PARAMETERS = -1;
  282.   USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = 1.0;
  283.   USER_OPTIONS->RATIO_TEMPERATURE_SCALES = FALSE;
  284.   USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = FALSE;
  285.  
  286.   USER_OPTIONS->TESTING_FREQUENCY_MODULUS = 100;
  287.   USER_OPTIONS->ACTIVATE_REANNEAL = TRUE;
  288.   USER_OPTIONS->REANNEAL_RESCALE = 10.0;
  289.   USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = 50000;
  290.  
  291.   USER_OPTIONS->DELTA_X = 0.001;
  292.   USER_OPTIONS->DELTA_PARAMETERS = FALSE;
  293.   USER_OPTIONS->USER_TANGENTS = FALSE;
  294.   USER_OPTIONS->CURVATURE_0 = FALSE;
  295.  
  296.   USER_OPTIONS->QUENCH_PARAMETERS = FALSE;
  297.   USER_OPTIONS->QUENCH_COST = FALSE;
  298. #endif /* OPTIONS_FILE */
  299. #endif /* SELF_OPTIMIZE */
  300.  
  301.   /* ALLOCATE STORAGE */
  302.  
  303. #if USER_ASA_OUT
  304.   if ((USER_OPTIONS->asa_out_file =
  305.        (char *) calloc (80, sizeof (char))
  306.       ) == NULL)
  307.       exit (9);
  308. #endif
  309.  
  310. #if ASA_TEST
  311.   /* the number of parameters for the cost function */
  312.   *parameter_dimension = 4;
  313.   /* end ASA_TEST */
  314. #else /* MY_COST */
  315.   /* the number of parameters for the cost function */
  316. #endif /* MY_COST */
  317.  
  318. #if ASA_SAMPLE
  319. #if ASA_TEMPLATE
  320.   *parameter_dimension = 2;
  321.   USER_OPTIONS->QUENCH_PARAMETERS = TRUE;
  322.   USER_OPTIONS->QUENCH_COST = TRUE;
  323.   USER_OPTIONS->USER_TANGENTS = TRUE;
  324. #endif
  325. #endif
  326. #if ASA_TEMPLATE
  327. #if ASA_PARALLEL
  328.   USER_OPTIONS->gener_block = 100;
  329.   USER_OPTIONS->gener_block_max = 512;
  330.   USER_OPTIONS->gener_mov_avr = 3;
  331. #endif
  332. #endif
  333.  
  334.   /* allocate parameter minimum space */
  335.   if ((parameter_lower_bound =
  336.        (double *) calloc (*parameter_dimension, sizeof (double))
  337.       ) == NULL)
  338.       exit (9);
  339.   /* allocate parameter maximum space */
  340.   if ((parameter_upper_bound =
  341.        (double *) calloc (*parameter_dimension, sizeof (double))
  342.       ) == NULL)
  343.       exit (9);
  344.   /* allocate parameter initial values; the parameter final values
  345.      will be stored here later */
  346.   if ((cost_parameters =
  347.        (double *) calloc (*parameter_dimension, sizeof (double))
  348.       ) == NULL)
  349.       exit (9);
  350.   /* allocate the parameter types, real or integer */
  351.   if ((parameter_int_real =
  352.        (int *) calloc (*parameter_dimension, sizeof (int))
  353.       ) == NULL)
  354.       exit (9);
  355.   /* allocate space for parameter cost_tangents -
  356.      used for reannealing */
  357.   if ((cost_tangents =
  358.        (double *) calloc (*parameter_dimension, sizeof (double))
  359.       ) == NULL)
  360.       exit (9);
  361.  
  362.   if (USER_OPTIONS->CURVATURE_0 == FALSE || USER_OPTIONS->CURVATURE_0 == -1)
  363.     {
  364.       /* allocate space for parameter cost_curvatures/covariance */
  365.       if ((cost_curvature =
  366.        (double *) calloc ((*parameter_dimension) *
  367.                   (*parameter_dimension),
  368.                   sizeof (double))) == NULL)
  369.       exit (9);
  370.     }
  371.   else
  372.     {
  373.       cost_curvature = (double *) NULL;
  374.     }
  375.  
  376. #if USER_COST_SCHEDULE
  377.   USER_OPTIONS->cost_schedule = user_cost_schedule;
  378. #endif
  379. #if USER_REANNEAL_FUNCTION
  380.   USER_OPTIONS->reanneal_function = user_reanneal;
  381. #endif
  382.  
  383.   initialize_parameters (cost_parameters,
  384.              parameter_lower_bound,
  385.              parameter_upper_bound,
  386.              cost_tangents,
  387.              cost_curvature,
  388.              parameter_dimension,
  389.              parameter_int_real,
  390.              USER_OPTIONS);
  391.  
  392.   /* optimize the cost_function, returning the results in
  393.      cost_value and cost_parameters */
  394. #if ASA_TEMPLATE
  395. #if USER_ASA_OUT
  396.   /* multiple asa() quenched calls + multiple asa_out files
  397.      (To get longer quenched runs, decrease SMALL_FLOAT.) */
  398.   for (n_asa = 1; n_asa <= *parameter_dimension; n_asa++)
  399.     {
  400.       asa_file[4] = 'A' + n_asa - 1;
  401.       if (USER_OPTIONS->QUENCH_COST == TRUE)
  402.     USER_OPTIONS->user_quench_cost_scale[0] = (double) n_asa;
  403.       if (USER_OPTIONS->QUENCH_PARAMETERS == TRUE)
  404.     for (index = 0; index < *parameter_dimension; ++index)
  405.       USER_OPTIONS->user_quench_param_scale[index] =
  406.         (double) n_asa;
  407.       for (n_trajectory = 0; n_trajectory < 3; ++n_trajectory)
  408.     {
  409.       asa_file[6] = 'a' + n_trajectory;
  410.       strcpy (USER_OPTIONS->asa_out_file, asa_file);
  411. #endif
  412. #endif
  413.  
  414.       cost_value =
  415.         asa (cost_function,
  416.          randflt,
  417.          cost_parameters,
  418.          parameter_lower_bound,
  419.          parameter_upper_bound,
  420.          cost_tangents,
  421.          cost_curvature,
  422.          parameter_dimension,
  423.          parameter_int_real,
  424.          cost_flag,
  425.          exit_code,
  426.          USER_OPTIONS);
  427.  
  428. #if TIME_CALC
  429.       /* print ending time */
  430.       print_time ("end", ptr_out);
  431. #endif
  432. #if ASA_TEMPLATE
  433. #if USER_ASA_OUT
  434.     }
  435.     }
  436. #endif
  437. #endif
  438.  
  439. #if ASA_SAMPLE
  440. #if ASA_TEMPLATE
  441. #if USER_ASA_OUT
  442.   ptr_asa = fopen (USER_OPTIONS->asa_out_file, "r");
  443. #else
  444.   ptr_asa = fopen ("asa_out", "r");
  445. #endif
  446.   sample (ptr_out, ptr_asa);
  447. #endif
  448. #endif
  449.  
  450.   /* close all files */
  451.   fclose (ptr_out);
  452. #if OPTIONAL_DATA
  453.   free (USER_OPTIONS->asa_data);
  454. #endif
  455. #if USER_ASA_OUT
  456.   free (USER_OPTIONS->asa_out_file);
  457. #endif
  458. #if ASA_SAMPLE
  459.   free (USER_OPTIONS->bias_generated);
  460. #endif
  461.   if (USER_OPTIONS->CURVATURE_0 == FALSE || USER_OPTIONS->CURVATURE_0 == -1)
  462.     free (cost_curvature);
  463.   if (USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS == TRUE)
  464.     free (USER_OPTIONS->user_parameter_temperature);
  465.   if (USER_OPTIONS->USER_INITIAL_COST_TEMP == TRUE)
  466.     free (USER_OPTIONS->user_cost_temperature);
  467.   if (USER_OPTIONS->DELTA_PARAMETERS == TRUE)
  468.     free (USER_OPTIONS->user_delta_parameter);
  469.   if (USER_OPTIONS->QUENCH_PARAMETERS == TRUE)
  470.     free (USER_OPTIONS->user_quench_param_scale);
  471.   if (USER_OPTIONS->QUENCH_COST == TRUE)
  472.     free (USER_OPTIONS->user_quench_cost_scale);
  473.   if (USER_OPTIONS->RATIO_TEMPERATURE_SCALES == TRUE)
  474.     free (USER_OPTIONS->user_temperature_ratio);
  475.   free (USER_OPTIONS);
  476.   free (parameter_dimension);
  477.   free (exit_code);
  478.   free (cost_flag);
  479.   free (parameter_lower_bound);
  480.   free (parameter_upper_bound);
  481.   free (cost_parameters);
  482.   free (parameter_int_real);
  483.   free (cost_tangents);
  484.  
  485. #if ASA_LIB
  486.   return (0);
  487. #else
  488.   exit (0);
  489.   /* NOTREACHED */
  490. #endif
  491. }
  492. #endif /* SELF_OPTIMIZE */
  493.  
  494. #if ASA_TEST
  495.  /* defines for the test problem, which assume *parameter_dimension
  496.     is a multiple of 4.  If this is set to a large number, you
  497.     likely should set CURVATURE_0 to TRUE. */
  498. #if __GNUC__
  499.  /* For _some_ versions of gcc the following may work */
  500.  /* #define ARRAY_LIMIT *parameter_dimension  */
  501. #define ARRAY_LIMIT    4    /* set equal to *parameter_dimension */
  502. #else
  503. #define ARRAY_LIMIT    4    /* set equal to *parameter_dimension */
  504. #endif
  505.  
  506. #define ARR_LMT4    (ARRAY_LIMIT/4)
  507. #endif /* ASA_TEST */
  508.  
  509. /***********************************************************************
  510. * initialize_parameters - sample parameter initialization function
  511. *    This depends on the users cost function to optimize (minimum).
  512. *    The routine allocates storage needed for asa. The user should
  513. *    define the number of parameters and their ranges,
  514. *    and make sure the initial parameters are within
  515. *    the minimum and maximum ranges. The array
  516. *    parameter_int_real should be REAL_TYPE (-1) for real parameters,
  517. *    and INTEGER_TYPE (1) for integer values
  518. ***********************************************************************/
  519. #if HAVE_ANSI
  520. void
  521. initialize_parameters (double *cost_parameters,
  522.                double *parameter_lower_bound,
  523.                double *parameter_upper_bound,
  524.                double *cost_tangents,
  525.                double *cost_curvature,
  526.                ALLOC_INT * parameter_dimension,
  527.                int *parameter_int_real,
  528.                USER_DEFINES * USER_OPTIONS)
  529. #else
  530. void
  531. initialize_parameters (cost_parameters,
  532.                parameter_lower_bound,
  533.                parameter_upper_bound,
  534.                cost_tangents,
  535.                cost_curvature,
  536.                parameter_dimension,
  537.                parameter_int_real,
  538.                USER_OPTIONS)
  539.      double *cost_parameters;
  540.      double *parameter_lower_bound;
  541.      double *parameter_upper_bound;
  542.      double *cost_tangents;
  543.      double *cost_curvature;
  544.      ALLOC_INT *parameter_dimension;
  545.      int *parameter_int_real;
  546.      USER_DEFINES *USER_OPTIONS;
  547. #endif
  548. {
  549.   ALLOC_INT index;
  550.  
  551. #if ASA_TEST
  552.   /* store the parameter ranges */
  553.   for (index = 0; index < *parameter_dimension; ++index)
  554.     parameter_lower_bound[index] = -10000.0;
  555.   for (index = 0; index < *parameter_dimension; ++index)
  556.     parameter_upper_bound[index] = 10000.0;
  557.  
  558.   /* store the initial parameter types */
  559.   for (index = 0; index < *parameter_dimension; ++index)
  560.     parameter_int_real[index] = REAL_TYPE;
  561.  
  562.   /* store the initial parameter values */
  563.   for (index = 0; index < ARR_LMT4; ++index)
  564.     {
  565.       cost_parameters[4 * (index + 1) - 4] = 999.0;
  566.       cost_parameters[4 * (index + 1) - 3] = -1007.0;
  567.       cost_parameters[4 * (index + 1) - 2] = 1001.0;
  568.       cost_parameters[4 * (index + 1) - 1] = -903.0;
  569.     }
  570.   /* end ASA_TEST */
  571. #else /* MY_COST */
  572.   /* store the parameter ranges */
  573.   /* store the initial parameter types */
  574.   /* store the initial parameter values */
  575. #endif /* MY_COST */
  576.  
  577. #if ASA_SAMPLE
  578. #if ASA_TEMPLATE
  579.   for (index = 0; index < *parameter_dimension; ++index)
  580.     parameter_lower_bound[index] = -1.0;
  581.   for (index = 0; index < *parameter_dimension; ++index)
  582.     parameter_upper_bound[index] = 1.0;
  583.   for (index = 0; index < *parameter_dimension; ++index)
  584.     parameter_int_real[index] = REAL_TYPE;
  585.   for (index = 0; index < *parameter_dimension; ++index)
  586.     cost_parameters[index] = 0.5;
  587. #endif
  588. #endif
  589.  
  590.   /* If USER_INITIAL_PARAMETERS_TEMPS=TRUE, then these must be
  591.      defined for all parameters. */
  592.   if (USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS == TRUE)
  593.     {
  594.       if ((USER_OPTIONS->user_parameter_temperature =
  595.        (double *) calloc (*parameter_dimension, sizeof (double))
  596.       ) == NULL)
  597.       exit (9);
  598.       for (index = 0; index < *parameter_dimension; ++index)
  599.     USER_OPTIONS->user_parameter_temperature[index] = 1.0;
  600.     }
  601.   /* If USER_INITIAL_COST_TEMP=TRUE, then this must be defined. */
  602.   if (USER_OPTIONS->USER_INITIAL_COST_TEMP == TRUE)
  603.     {
  604.       if ((USER_OPTIONS->user_cost_temperature =
  605.        (double *) calloc (1, sizeof (double))) == NULL)
  606.       exit (9);
  607.       USER_OPTIONS->user_cost_temperature[0] = 5.936648E+09;
  608.     }
  609.   /* If DELTA_PARAMETERS=TRUE, then these must be defined for
  610.      all parameters that will be pseudo-differentiated. */
  611.   if (USER_OPTIONS->DELTA_PARAMETERS == TRUE)
  612.     {
  613.       if ((USER_OPTIONS->user_delta_parameter =
  614.        (double *) calloc (*parameter_dimension, sizeof (double))
  615.       ) == NULL)
  616.       exit (9);
  617.       for (index = 0; index < *parameter_dimension; ++index)
  618.     USER_OPTIONS->user_delta_parameter[index] = 0.001;
  619.     }
  620.   /* If QUENCH_PARAMETERS=TRUE, then these must be defined for
  621.      all parameters. */
  622.   if (USER_OPTIONS->QUENCH_PARAMETERS == TRUE)
  623.     {
  624.       if ((USER_OPTIONS->user_quench_param_scale =
  625.        (double *) calloc (*parameter_dimension, sizeof (double))
  626.       ) == NULL)
  627.       exit (9);
  628.       for (index = 0; index < *parameter_dimension; ++index)
  629.     USER_OPTIONS->user_quench_param_scale[index] = 1.0;
  630.     }
  631.   /* If QUENCH_COST=TRUE, then this must be defined. */
  632.   if (USER_OPTIONS->QUENCH_COST == TRUE)
  633.     {
  634.       if ((USER_OPTIONS->user_quench_cost_scale =
  635.        (double *) calloc (1, sizeof (double))) == NULL)
  636.       exit (9);
  637.       USER_OPTIONS->user_quench_cost_scale[0] = 1.0;
  638.     }
  639.   /* If RATIO_TEMPERATURE_SCALES=TRUE, then these must be defined
  640.      for all parameters. */
  641.   if (USER_OPTIONS->RATIO_TEMPERATURE_SCALES == TRUE)
  642.     {
  643.       if ((USER_OPTIONS->user_temperature_ratio =
  644.        (double *) calloc (*parameter_dimension, sizeof (double))
  645.       ) == NULL)
  646.       exit (9);
  647.       for (index = 0; index < *parameter_dimension; ++index)
  648.     USER_OPTIONS->user_temperature_ratio[index] = 1.0;
  649.     }
  650.   /* Defines the limit of collection of sampled data by asa */
  651. #if ASA_SAMPLE
  652.   /* create memory for bias_generated[] */
  653.   if ((USER_OPTIONS->bias_generated =
  654.        (double *) calloc (*parameter_dimension, sizeof (double))
  655.       ) == NULL)
  656.       exit (9);
  657.  
  658. #if ASA_TEMPLATE
  659.   USER_OPTIONS->limit_weights = 1.0E-7;
  660.   if (USER_OPTIONS->QUENCH_COST == TRUE)
  661.     USER_OPTIONS->user_quench_cost_scale[0] = 1.0;
  662.   if (USER_OPTIONS->QUENCH_PARAMETERS == TRUE)
  663.     for (index = 0; index < *parameter_dimension; ++index)
  664.       USER_OPTIONS->user_quench_param_scale[index] = 1.0;
  665. #endif
  666. #endif
  667. }
  668. /***********************************************************************
  669. * double cost_function
  670. *    This is the users cost function to optimize
  671. *    (find the minimum).
  672. *    cost_flag is set to true if the parameter set
  673. *    does not violates any constraints
  674. *       parameter_lower_bound and parameter_upper_bound may be
  675. *       adaptively changed during the search.
  676. ***********************************************************************/
  677.  
  678. #if HAVE_ANSI
  679. double
  680. cost_function (double *x,
  681.            double *parameter_lower_bound,
  682.            double *parameter_upper_bound,
  683.            double *cost_tangents,
  684.            double *cost_curvature,
  685.            ALLOC_INT * parameter_dimension,
  686.            int *parameter_int_real,
  687.            int *cost_flag,
  688.            int *exit_code,
  689.            USER_DEFINES * USER_OPTIONS)
  690. #else
  691. double
  692. cost_function (x,
  693.            parameter_lower_bound,
  694.            parameter_upper_bound,
  695.            cost_tangents,
  696.            cost_curvature,
  697.            parameter_dimension,
  698.            parameter_int_real,
  699.            cost_flag,
  700.            exit_code,
  701.            USER_OPTIONS)
  702.      double *x;
  703.      double *parameter_lower_bound;
  704.      double *parameter_upper_bound;
  705.      double *cost_tangents;
  706.      double *cost_curvature;
  707.      ALLOC_INT *parameter_dimension;
  708.      int *parameter_int_real;
  709.      int *cost_flag;
  710.      int *exit_code;
  711.      USER_DEFINES *USER_OPTIONS;
  712. #endif
  713. {
  714.  
  715. #if ASA_TEST            /* ASA test problem */
  716. /* Objective function from
  717.    * %A A. Corana
  718.    * %A M. Marchesi
  719.    * %A C. Martini
  720.    * %A S. Ridella
  721.    * %T Minimizing multimodal functions of continuous variables
  722.    *    with the "simulated annealing" algorithm
  723.    * %J ACM Trans. Mathl. Software
  724.    * %V 13
  725.    * %N 3
  726.    * %P 262-279
  727.    * %D 1987
  728.    *
  729.    * This function contains 1.0E20 local minima.  When *parameter_dimension
  730.    * is equal to 4, visiting each minimum for a millisecond would take
  731.    * about the present age of the universe to visit all these minima. */
  732.  
  733.   double d[ARRAY_LIMIT];
  734.   double q_n, s_i, t_i, z_i, c_r;
  735.   int k_i;
  736.   LONG_INT i;
  737. #if SELF_OPTIMIZE
  738. #else
  739.   static LONG_INT funevals = 0;
  740. #endif
  741.  
  742.   /* a_i = parameter_upper_bound[i] */
  743.   s_i = 0.2;
  744.   t_i = 0.05;
  745.   c_r = 0.15;
  746.  
  747.   for (i = 0; i < ARR_LMT4; ++i)
  748.     {
  749.       d[4 * (i + 1) - 4] = 1.0;
  750.       d[4 * (i + 1) - 3] = 1000.0;
  751.       d[4 * (i + 1) - 2] = 10.0;
  752.       d[4 * (i + 1) - 1] = 100.0;
  753.     }
  754.  
  755.   q_n = 0.0;
  756.   for (i = 0; i < ARRAY_LIMIT; ++i)
  757.     {
  758.       if (x[i] > 0.0)
  759.     {
  760.       k_i = (int) (x[i] / s_i + 0.5);
  761.     }
  762.       else if (x[i] < 0.0)
  763.     {
  764.       k_i = (int) (x[i] / s_i - 0.5);
  765.     }
  766.       else
  767.     {
  768.       k_i = 0;
  769.     }
  770.  
  771.       if (fabs (k_i * s_i - x[i]) < t_i)
  772.     {
  773.       if (k_i < 0)
  774.         {
  775.           z_i = k_i * s_i + t_i;
  776.         }
  777.       else if (k_i > 0)
  778.         {
  779.           z_i = k_i * s_i - t_i;
  780.         }
  781.       else
  782.         {
  783.           z_i = 0.0;
  784.         }
  785.       q_n += c_r * d[i] * z_i * z_i;
  786.     }
  787.       else
  788.     {
  789.       q_n += d[i] * x[i] * x[i];
  790.     }
  791.     }
  792.   funevals = funevals + 1;
  793.  
  794.   *cost_flag = TRUE;
  795.  
  796. #if SELF_OPTIMIZE
  797. #else
  798. #if TIME_CALC
  799.   /* print the time every PRINT_FREQUENCY evaluations */
  800.   if ((PRINT_FREQUENCY > 0) && ((funevals % PRINT_FREQUENCY) == 0))
  801.     {
  802.       fprintf (ptr_out, "funevals = %ld  ", funevals);
  803.       print_time ("", ptr_out);
  804.     }
  805. #endif
  806. #endif
  807.   return (q_n);
  808.   /* end ASA_TEST */
  809. #else /* MY_COST */
  810.   /* use the parameter values x[] to define your cost function */
  811. #endif /* MY_COST */
  812.  
  813. #if ASA_SAMPLE
  814. #if ASA_TEMPLATE
  815.  
  816.   int n, m;
  817.   double cost, tmp_dbl;
  818.  
  819.   if (*cost_flag == FALSE)
  820.     {
  821.       for (m = 0; m < *parameter_dimension; ++m)
  822.     {
  823.       tmp_dbl = 1.0;
  824.       for (n = 0; n < *parameter_dimension; ++n)
  825.         {
  826.           if (n == m)
  827.         continue;
  828.           tmp_dbl *= (x[n] * x[n] * (1.0 - x[n] * x[n]));
  829.         }
  830.       cost_tangents[m] = -tmp_dbl * 2.0 * x[m] * (1.0 - 2.0 * x[m] * x[m]);
  831.     }
  832.     }
  833.  
  834.   cost = 1.0;
  835.   for (n = 0; n < *parameter_dimension; ++n)
  836.     {
  837.       cost *= (x[n] * x[n] * (1.0 - x[n] * x[n]));
  838.     }
  839.  
  840.   *cost_flag = TRUE;
  841.  
  842.   return (-cost);
  843. #endif /* ASA_TEMPLATE */
  844. #endif /* ASA_SAMPLE */
  845.  
  846. }
  847.  
  848.  /* Here is a good random number generator */
  849.  
  850. #define SHUFFLE 256        /* size of random array */
  851. #define MULT ((LONG_INT) 25173)
  852. #define MOD ((LONG_INT) 65536)
  853. #define INCR ((LONG_INT) 13849)
  854. #define FMOD ((double) 65536.0)
  855.  
  856. static LONG_INT seed = 696969;
  857. double random_array[SHUFFLE];    /* random variables */
  858.  
  859. /***********************************************************************
  860. * double myrand(void) - returns a random number between 0 and 1
  861. *    This routine returns the random number generator between 0 and 1
  862. ***********************************************************************/
  863.  
  864. #if HAVE_ANSI
  865. double
  866. myrand (void)
  867. #else
  868. double
  869. myrand ()
  870. #endif
  871.  /* returns random number in {0,1} */
  872. {
  873.   seed = (LONG_INT) ((MULT * seed + INCR) % MOD);
  874.   return ((double) seed / FMOD);
  875. }
  876.  
  877. /***********************************************************************
  878. * double randflt(void)
  879. *    Shuffles random numbers in random_array[]
  880. ***********************************************************************/
  881.  
  882. #if HAVE_ANSI
  883. double
  884. randflt (void)
  885. #else
  886. double
  887. randflt ()
  888. #endif
  889.  /* shuffles random numbers in random_array[SHUFFLE] array */
  890. {
  891.  
  892. /* This RNG is a modified algorithm of that presented in
  893.    * %A K. Binder
  894.    * %A D. Stauffer
  895.    * %T A simple introduction to Monte Carlo simulations and some
  896.    *    specialized topics
  897.    * %B Applications of the Monte Carlo Method in statistical physics
  898.    * %E K. Binder
  899.    * %I Springer-Verlag
  900.    * %C Berlin
  901.    * %D 1985
  902.    * %P 1-36
  903.    * where it is stated that such algorithms have been found to be
  904.    * quite satisfactory in many statistical physics applications. */
  905.  
  906.   double rranf;
  907.   unsigned kranf;
  908.  
  909.   kranf = (unsigned) (myrand () * SHUFFLE) % SHUFFLE;
  910.   rranf = *(random_array + kranf);
  911.   *(random_array + kranf) = myrand ();
  912.  
  913.   return (rranf);
  914. }
  915.  
  916. /***********************************************************************
  917. * initialize_rng()
  918. *    This routine initializes the random number generator
  919. ***********************************************************************/
  920.  
  921. #if HAVE_ANSI
  922. void
  923. initialize_rng (void)
  924. #else
  925. void
  926. initialize_rng ()
  927. #endif
  928. {
  929.   int n;
  930.   double x;
  931.  
  932.   for (n = 0; n < SHUFFLE; ++n)
  933.     random_array[n] = myrand ();
  934.   for (n = 0; n < 1000; ++n)    /* warm up random generator */
  935.     x = randflt ();
  936. }
  937.  
  938. #if USER_COST_SCHEDULE
  939. #if HAVE_ANSI
  940. double
  941. user_cost_schedule (double test_temperature,
  942.             USER_DEFINES * USER_OPTIONS)
  943. #else
  944. double
  945. user_cost_schedule (test_temperature,
  946.             USER_OPTIONS)
  947.      double test_temperature;
  948.      USER_DEFINES *USER_OPTIONS;
  949. #endif /* HAVE_ANSI */
  950. {
  951. #if ASA_TEMPLATE
  952.   double x;
  953.  
  954. #if ASA_SAMPLE
  955. #if ASA_TEMPLATE
  956.   x = pow (test_temperature, 0.25);
  957. #endif
  958.  
  959. #else
  960.   x = test_temperature;
  961. #endif
  962.  
  963.   return (x);
  964. #endif
  965. }
  966. #endif /* USER_COST_SCHEDULE */
  967.  
  968. #if USER_REANNEAL_FUNCTION
  969. #if HAVE_ANSI
  970. double
  971. user_reanneal (double current_temp,
  972.            double tangent,
  973.            double max_tangent,
  974.            USER_DEFINES * USER_OPTIONS)
  975. #else
  976. double
  977. user_reanneal (current_temp,
  978.            tangent,
  979.            max_tangent,
  980.            USER_OPTIONS)
  981.      double current_temp;
  982.      double tangent;
  983.      double max_tangent;
  984.      USER_DEFINES *USER_OPTIONS;
  985. #endif /* HAVE_ANSI */
  986. {
  987. #if ASA_TEMPLATE
  988.   double x;
  989.  
  990.   x = current_temp * (max_tangent / tangent);
  991.  
  992.   return (x);
  993. #endif
  994. }
  995. #endif /* USER_REANNEAL_FUNCTION */
  996.  
  997. #if SELF_OPTIMIZE
  998.  
  999. /***********************************************************************
  1000. * main
  1001. *    This is a sample calling program to self-optimize ASA
  1002. ***********************************************************************/
  1003. #if HAVE_ANSI
  1004. #if ASA_LIB
  1005. int
  1006. asa_main ()
  1007. #else
  1008. int
  1009. main (int argc, char **argv)
  1010. #endif
  1011. #else
  1012. #if ASA_LIB
  1013. int
  1014. asa_main ()
  1015. #else
  1016. int
  1017. main (argc, argv)
  1018.      int argc;
  1019.      char **argv;
  1020. #endif
  1021. #endif
  1022. {
  1023. #if OPTIONS_FILE
  1024.   FILE *ptr_options;
  1025.   char read_option[80];
  1026.   int read_int;
  1027.   LONG_INT read_long;
  1028.   double read_double;
  1029. #endif
  1030.  
  1031.   int *recur_exit_code;
  1032. #if ASA_LIB
  1033. #else
  1034.   int compile_cnt;
  1035. #endif
  1036.  
  1037.   double *recur_parameter_lower_bound, *recur_parameter_upper_bound;
  1038.   double *recur_cost_parameters, *recur_cost_tangents, *recur_cost_curvature;
  1039.   double recur_cost_value;
  1040.  
  1041.   ALLOC_INT *recur_parameter_dimension;
  1042.   int *recur_parameter_int_real;
  1043.   int *recur_cost_flag;
  1044.   int recur_v;
  1045.  
  1046.   USER_DEFINES *RECUR_USER_OPTIONS;
  1047.  
  1048.   if ((recur_parameter_dimension =
  1049.        (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL)
  1050.     exit (9);
  1051.   if ((recur_exit_code = (int *) calloc (1, sizeof (int))) == NULL)
  1052.       exit (9);
  1053.   if ((recur_cost_flag = (int *) calloc (1, sizeof (int))) == NULL)
  1054.       exit (9);
  1055.  
  1056.   if ((RECUR_USER_OPTIONS =
  1057.        (USER_DEFINES *) calloc (1, sizeof (USER_DEFINES))) == NULL)
  1058.     exit (9);
  1059.  
  1060. #if OPTIONS_FILE
  1061.   ptr_options = fopen ("asa_opt", "r");
  1062.  
  1063. #if INT_LONG
  1064.   fscanf (ptr_options, "%s", read_option);
  1065.   fscanf (ptr_options, "%ld", &read_long);
  1066.   RECUR_USER_OPTIONS->LIMIT_ACCEPTANCES = read_long;
  1067.   fscanf (ptr_options, "%s", read_option);
  1068.   fscanf (ptr_options, "%ld", &read_long);
  1069.   RECUR_USER_OPTIONS->LIMIT_GENERATED = read_long;
  1070. #else
  1071.   fscanf (ptr_options, "%s", read_option);
  1072.   fscanf (ptr_options, "%d", &read_int);
  1073.   RECUR_USER_OPTIONS->LIMIT_ACCEPTANCES = read_int;
  1074.   fscanf (ptr_options, "%s", read_option);
  1075.   fscanf (ptr_options, "%d", &read_int);
  1076.   RECUR_USER_OPTIONS->LIMIT_GENERATED = read_int;
  1077. #endif
  1078.   fscanf (ptr_options, "%s", read_option);
  1079.   fscanf (ptr_options, "%d", &read_int);
  1080.   RECUR_USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = read_int;
  1081.   fscanf (ptr_options, "%s", read_option);
  1082.   fscanf (ptr_options, "%lf", &read_double);
  1083.   RECUR_USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = read_double;
  1084.  
  1085.   fscanf (ptr_options, "%s", read_option);
  1086.   fscanf (ptr_options, "%lf", &read_double);
  1087.   RECUR_USER_OPTIONS->COST_PRECISION = read_double;
  1088.   fscanf (ptr_options, "%s", read_option);
  1089.   fscanf (ptr_options, "%d", &read_int);
  1090.   RECUR_USER_OPTIONS->MAXIMUM_COST_REPEAT = read_int;
  1091.   fscanf (ptr_options, "%s", read_option);
  1092.   fscanf (ptr_options, "%d", &read_int);
  1093.   RECUR_USER_OPTIONS->NUMBER_COST_SAMPLES = read_int;
  1094.   fscanf (ptr_options, "%s", read_option);
  1095.   fscanf (ptr_options, "%lf", &read_double);
  1096.   RECUR_USER_OPTIONS->TEMPERATURE_RATIO_SCALE = read_double;
  1097.   fscanf (ptr_options, "%s", read_option);
  1098.   fscanf (ptr_options, "%lf", &read_double);
  1099.   RECUR_USER_OPTIONS->COST_PARAMETER_SCALE = read_double;
  1100.   fscanf (ptr_options, "%s", read_option);
  1101.   fscanf (ptr_options, "%lf", &read_double);
  1102.   RECUR_USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = read_double;
  1103.   fscanf (ptr_options, "%s", read_option);
  1104.   fscanf (ptr_options, "%d", &read_int);
  1105.   RECUR_USER_OPTIONS->USER_INITIAL_COST_TEMP = read_int;
  1106.  
  1107.   fscanf (ptr_options, "%s", read_option);
  1108.   fscanf (ptr_options, "%d", &read_int);
  1109.   RECUR_USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = read_int;
  1110.   fscanf (ptr_options, "%s", read_option);
  1111.   fscanf (ptr_options, "%d", &read_int);
  1112.   RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS = read_int;
  1113. #if INT_ALLOC
  1114.   fscanf (ptr_options, "%s", read_option);
  1115.   fscanf (ptr_options, "%d", &read_int);
  1116.   RECUR_USER_OPTIONS->SEQUENTIAL_PARAMETERS = read_int;
  1117. #else
  1118. #if INT_LONG
  1119.   fscanf (ptr_options, "%s", read_option);
  1120.   fscanf (ptr_options, "%ld", &read_long);
  1121.   RECUR_USER_OPTIONS->SEQUENTIAL_PARAMETERS = read_long;
  1122. #else
  1123.   fscanf (ptr_options, "%s", read_option);
  1124.   fscanf (ptr_options, "%d", &read_int);
  1125.   RECUR_USER_OPTIONS->SEQUENTIAL_PARAMETERS = read_int;
  1126. #endif
  1127. #endif
  1128.   fscanf (ptr_options, "%s", read_option);
  1129.   fscanf (ptr_options, "%lf", &read_double);
  1130.   RECUR_USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = read_double;
  1131.   fscanf (ptr_options, "%s", read_option);
  1132.   fscanf (ptr_options, "%d", &read_int);
  1133.   RECUR_USER_OPTIONS->RATIO_TEMPERATURE_SCALES = read_int;
  1134.   fscanf (ptr_options, "%s", read_option);
  1135.   fscanf (ptr_options, "%d", &read_int);
  1136.   RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = read_int;
  1137.  
  1138.   fscanf (ptr_options, "%s", read_option);
  1139.   fscanf (ptr_options, "%d", &read_int);
  1140.   RECUR_USER_OPTIONS->TESTING_FREQUENCY_MODULUS = read_int;
  1141.   fscanf (ptr_options, "%s", read_option);
  1142.   fscanf (ptr_options, "%d", &read_int);
  1143.   RECUR_USER_OPTIONS->ACTIVATE_REANNEAL = read_int;
  1144.   fscanf (ptr_options, "%s", read_option);
  1145.   fscanf (ptr_options, "%lf", &read_double);
  1146.   RECUR_USER_OPTIONS->REANNEAL_RESCALE = read_double;
  1147.   fscanf (ptr_options, "%s", read_option);
  1148. #if INT_LONG
  1149.   fscanf (ptr_options, "%ld", &read_long);
  1150. #else
  1151.   fscanf (ptr_options, "%d", &read_long);
  1152. #endif
  1153.   RECUR_USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = read_long;
  1154.  
  1155.   fscanf (ptr_options, "%s", read_option);
  1156.   fscanf (ptr_options, "%lf", &read_double);
  1157.   RECUR_USER_OPTIONS->DELTA_X = read_double;
  1158.   fscanf (ptr_options, "%s", read_option);
  1159.   fscanf (ptr_options, "%d", &read_int);
  1160.   RECUR_USER_OPTIONS->DELTA_PARAMETERS = read_int;
  1161.   fscanf (ptr_options, "%s", read_option);
  1162.   fscanf (ptr_options, "%d", &read_int);
  1163.   RECUR_USER_OPTIONS->USER_TANGENTS = read_int;
  1164.   fscanf (ptr_options, "%s", read_option);
  1165.   fscanf (ptr_options, "%d", &read_int);
  1166.   RECUR_USER_OPTIONS->CURVATURE_0 = read_int;
  1167.  
  1168.   fscanf (ptr_options, "%s", read_option);
  1169.   fscanf (ptr_options, "%d", &read_int);
  1170.   RECUR_USER_OPTIONS->QUENCH_PARAMETERS = read_int;
  1171.   fscanf (ptr_options, "%s", read_option);
  1172.   fscanf (ptr_options, "%d", &read_int);
  1173.   RECUR_USER_OPTIONS->QUENCH_COST = read_int;
  1174.  
  1175.   fclose (ptr_options);
  1176. #else /* OPTIONS_FILE */
  1177.   RECUR_USER_OPTIONS->LIMIT_ACCEPTANCES = 100;
  1178.   RECUR_USER_OPTIONS->LIMIT_GENERATED = 1000;
  1179.   RECUR_USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = 1000;
  1180.   RECUR_USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = 1.0E-4;
  1181.  
  1182.   RECUR_USER_OPTIONS->COST_PRECISION = 1.0E-18;
  1183.   RECUR_USER_OPTIONS->MAXIMUM_COST_REPEAT = 2;
  1184.   RECUR_USER_OPTIONS->NUMBER_COST_SAMPLES = 2;
  1185.   RECUR_USER_OPTIONS->TEMPERATURE_RATIO_SCALE = 1.0E-5;
  1186.   RECUR_USER_OPTIONS->COST_PARAMETER_SCALE = 1.0;
  1187.   RECUR_USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = 100.0;
  1188.   RECUR_USER_OPTIONS->USER_INITIAL_COST_TEMP = FALSE;
  1189.  
  1190.   RECUR_USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = FALSE;
  1191.   RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS = TRUE;
  1192.   RECUR_USER_OPTIONS->SEQUENTIAL_PARAMETERS = -1;
  1193.   RECUR_USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = 1.0;
  1194.   RECUR_USER_OPTIONS->RATIO_TEMPERATURE_SCALES = FALSE;
  1195.   RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = FALSE;
  1196.  
  1197.   RECUR_USER_OPTIONS->TESTING_FREQUENCY_MODULUS = 15;
  1198.   RECUR_USER_OPTIONS->ACTIVATE_REANNEAL = FALSE;
  1199.   RECUR_USER_OPTIONS->REANNEAL_RESCALE = 10.0;
  1200.   RECUR_USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = 50000;
  1201.  
  1202.   RECUR_USER_OPTIONS->DELTA_X = 1.0E-6;
  1203.   RECUR_USER_OPTIONS->DELTA_PARAMETERS = FALSE;
  1204.   RECUR_USER_OPTIONS->USER_TANGENTS = FALSE;
  1205.   RECUR_USER_OPTIONS->CURVATURE_0 = TRUE;
  1206.  
  1207.   RECUR_USER_OPTIONS->QUENCH_PARAMETERS = FALSE;
  1208.   RECUR_USER_OPTIONS->QUENCH_COST = FALSE;
  1209.  
  1210. #endif /* OPTIONS_FILE */
  1211.  
  1212. #if ASA_TEMPLATE
  1213.   *recur_parameter_dimension = 2;
  1214. #endif
  1215.  
  1216.   if ((recur_parameter_lower_bound =
  1217.        (double *) calloc (*recur_parameter_dimension, sizeof (double))
  1218.       ) == NULL)
  1219.       exit (9);
  1220.   if ((recur_parameter_upper_bound =
  1221.        (double *) calloc (*recur_parameter_dimension, sizeof (double))
  1222.       ) == NULL)
  1223.       exit (9);
  1224.  
  1225.   if ((recur_cost_parameters =
  1226.        (double *) calloc (*recur_parameter_dimension, sizeof (double))
  1227.       ) == NULL)
  1228.       exit (9);
  1229.  
  1230.   if ((recur_parameter_int_real =
  1231.        (int *) calloc (*recur_parameter_dimension, sizeof (int))
  1232.       ) == NULL)
  1233.       exit (9);
  1234.  
  1235.   if ((recur_cost_tangents =
  1236.        (double *) calloc (*recur_parameter_dimension, sizeof (double))
  1237.       ) == NULL)
  1238.       exit (9);
  1239.  
  1240.   if (RECUR_USER_OPTIONS->CURVATURE_0 == FALSE
  1241.       || RECUR_USER_OPTIONS->CURVATURE_0 == -1)
  1242.     {
  1243.  
  1244.       if ((recur_cost_curvature =
  1245.        (double *) calloc ((*recur_parameter_dimension)
  1246.                   * (*recur_parameter_dimension),
  1247.                   sizeof (double))) == NULL)
  1248.       exit (9);
  1249.     }
  1250.   else
  1251.     {
  1252.       recur_cost_curvature = (double *) NULL;
  1253.     }
  1254.  
  1255. #if OPTIONAL_DATA
  1256.   /* Set memory to that required for use. */
  1257.   if ((RECUR_USER_OPTIONS->asa_data =
  1258.        (double *) calloc (1, sizeof (double))) == NULL)
  1259.       exit (9);
  1260.   /* Use asa_data[0] as flag, e.g., if used with SELF_OPTIMIZE. */
  1261.   RECUR_USER_OPTIONS->asa_data[0] = 0;
  1262. #endif
  1263.  
  1264.   /* open the output file */
  1265.   ptr_out = fopen ("user_out", "w");
  1266.   /* use this instead if you want output to stdout */
  1267. #if FALSE
  1268.   ptr_out = stdout;
  1269. #endif
  1270.   fprintf (ptr_out, "%s\n\n", USER_ID);
  1271.  
  1272. #if ASA_LIB
  1273. #else
  1274.   /* print out compile options set by user in Makefile */
  1275.   if (argc > 1)
  1276.     {
  1277.       fprintf (ptr_out, "CC = %s\n", argv[1]);
  1278.       for (compile_cnt = 2; compile_cnt < argc; ++compile_cnt)
  1279.     {
  1280.       fprintf (ptr_out, "\t%s\n", argv[compile_cnt]);
  1281.     }
  1282.       fprintf (ptr_out, "\n");
  1283.     }
  1284. #endif
  1285. #if TIME_CALC
  1286.   /* print starting time */
  1287.   print_time ("start", ptr_out);
  1288. #endif
  1289.   fflush (ptr_out);
  1290.  
  1291.   initialize_rng ();
  1292.  
  1293. #if USER_COST_SCHEDULE
  1294.   RECUR_USER_OPTIONS->cost_schedule = recur_user_cost_schedule;
  1295. #endif
  1296. #if USER_REANNEAL_FUNCTION
  1297.   RECUR_USER_OPTIONS->reanneal_function = recur_user_reanneal;
  1298. #endif
  1299.  
  1300.   /* initialize the users parameters, allocating space, etc.
  1301.      Note that the default is to have asa generate the initial
  1302.      recur_cost_parameters that satisfy the user's constraints. */
  1303.  
  1304.   recur_initialize_parameters (recur_cost_parameters,
  1305.                    recur_parameter_lower_bound,
  1306.                    recur_parameter_upper_bound,
  1307.                    recur_cost_tangents,
  1308.                    recur_cost_curvature,
  1309.                    recur_parameter_dimension,
  1310.                    recur_parameter_int_real,
  1311.                    RECUR_USER_OPTIONS);
  1312.  
  1313. #if USER_ASA_OUT
  1314.   if ((RECUR_USER_OPTIONS->asa_out_file =
  1315.        (char *) calloc (80, sizeof (char))
  1316.       ) == NULL)
  1317.       exit (9);
  1318. #if ASA_TEMPLATE
  1319.   strcpy (RECUR_USER_OPTIONS->asa_out_file, "asa_sfop");
  1320. #endif
  1321. #endif
  1322.   recur_cost_value = asa (recur_cost_function,
  1323.               randflt,
  1324.               recur_cost_parameters,
  1325.               recur_parameter_lower_bound,
  1326.               recur_parameter_upper_bound,
  1327.               recur_cost_tangents,
  1328.               recur_cost_curvature,
  1329.               recur_parameter_dimension,
  1330.               recur_parameter_int_real,
  1331.               recur_cost_flag,
  1332.               recur_exit_code,
  1333.               RECUR_USER_OPTIONS);
  1334.   fprintf (ptr_out, "\n\n recur_cost_value = %g\n",
  1335.        recur_cost_value);
  1336.  
  1337.   for (recur_v = 0; recur_v < *recur_parameter_dimension; ++recur_v)
  1338.     fprintf (ptr_out, "recur_cost_parameters[%d] = %g\n",
  1339.          recur_v, recur_cost_parameters[recur_v]);
  1340.  
  1341.   fprintf (ptr_out, "\n\n");
  1342.  
  1343. #if TIME_CALC
  1344.   /* print ending time */
  1345.   print_time ("end", ptr_out);
  1346. #endif
  1347.  
  1348.   /* close all files */
  1349.   fclose (ptr_out);
  1350.  
  1351. #if OPTIONAL_DATA
  1352.   free (RECUR_USER_OPTIONS->asa_data);
  1353. #endif
  1354. #if USER_ASA_OUT
  1355.   free (RECUR_USER_OPTIONS->asa_out_file);
  1356. #endif
  1357. #if ASA_SAMPLE
  1358.   free (RECUR_USER_OPTIONS->bias_generated);
  1359. #endif
  1360.   if (RECUR_USER_OPTIONS->CURVATURE_0 == FALSE
  1361.       || RECUR_USER_OPTIONS->CURVATURE_0 == -1)
  1362.     free (recur_cost_curvature);
  1363.   if (RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS == TRUE)
  1364.     free (RECUR_USER_OPTIONS->user_parameter_temperature);
  1365.   if (RECUR_USER_OPTIONS->USER_INITIAL_COST_TEMP == TRUE)
  1366.     free (RECUR_USER_OPTIONS->user_cost_temperature);
  1367.   if (RECUR_USER_OPTIONS->DELTA_PARAMETERS == TRUE)
  1368.     free (RECUR_USER_OPTIONS->user_delta_parameter);
  1369.   if (RECUR_USER_OPTIONS->QUENCH_PARAMETERS == TRUE)
  1370.     free (RECUR_USER_OPTIONS->user_quench_param_scale);
  1371.   if (RECUR_USER_OPTIONS->QUENCH_COST == TRUE)
  1372.     free (RECUR_USER_OPTIONS->user_quench_cost_scale);
  1373.   if (RECUR_USER_OPTIONS->RATIO_TEMPERATURE_SCALES == TRUE)
  1374.     free (RECUR_USER_OPTIONS->user_temperature_ratio);
  1375.   free (RECUR_USER_OPTIONS);
  1376.   free (recur_parameter_dimension);
  1377.   free (recur_exit_code);
  1378.   free (recur_cost_flag);
  1379.   free (recur_parameter_lower_bound);
  1380.   free (recur_parameter_upper_bound);
  1381.   free (recur_cost_parameters);
  1382.   free (recur_parameter_int_real);
  1383.   free (recur_cost_tangents);
  1384.  
  1385. #if ASA_LIB
  1386.   return (0);
  1387. #else
  1388.   exit (0);
  1389.   /* NOTREACHED */
  1390. #endif
  1391. }
  1392.  
  1393. /***********************************************************************
  1394. * recur_initialize_parameters
  1395. *    This depends on the users cost function to optimize (minimum).
  1396. *    The routine allocates storage needed for asa. The user should
  1397. *    define the number of parameters and their ranges,
  1398. *    and make sure the initial parameters are within
  1399. *    the minimum and maximum ranges. The array
  1400. *    recur_parameter_int_real should be REAL_TYPE (-1)
  1401. *       for real parameters,
  1402. ***********************************************************************/
  1403. #if HAVE_ANSI
  1404. void
  1405. recur_initialize_parameters (double *recur_cost_parameters,
  1406.                  double *recur_parameter_lower_bound,
  1407.                  double *recur_parameter_upper_bound,
  1408.                  double *recur_cost_tangents,
  1409.                  double *recur_cost_curvature,
  1410.                  ALLOC_INT * recur_parameter_dimension,
  1411.                  int *recur_parameter_int_real,
  1412.                  USER_DEFINES * RECUR_USER_OPTIONS)
  1413. #else
  1414. void
  1415. recur_initialize_parameters (recur_cost_parameters,
  1416.                  recur_parameter_lower_bound,
  1417.                  recur_parameter_upper_bound,
  1418.                  recur_cost_tangents,
  1419.                  recur_cost_curvature,
  1420.                  recur_parameter_dimension,
  1421.                  recur_parameter_int_real,
  1422.                  RECUR_USER_OPTIONS)
  1423.      double *recur_parameter_lower_bound;
  1424.      double *recur_parameter_upper_bound;
  1425.      double *recur_cost_parameters;
  1426.      double *recur_cost_tangents;
  1427.      double *recur_cost_curvature;
  1428.      ALLOC_INT *recur_parameter_dimension;
  1429.      int *recur_parameter_int_real;
  1430.      USER_DEFINES *RECUR_USER_OPTIONS;
  1431. #endif
  1432. {
  1433.   ALLOC_INT index;
  1434.  
  1435. #if ASA_TEMPLATE
  1436.   /*
  1437.      USER_OPTIONS->TEMPERATURE_RATIO_SCALE = x[0];
  1438.      USER_OPTIONS->COST_PARAMETER_SCALE = x[1];
  1439.    */
  1440.  
  1441.   /* store the initial parameter values */
  1442.   recur_cost_parameters[0] = 1.0E-5;
  1443.   recur_cost_parameters[1] = 1.0;
  1444.  
  1445.   recur_parameter_lower_bound[0] = 1.0E-6;
  1446.   recur_parameter_upper_bound[0] = 1.0E-4;
  1447.  
  1448.   recur_parameter_lower_bound[1] = 0.5;
  1449.   recur_parameter_upper_bound[1] = 3.0;
  1450. #endif
  1451.  
  1452.   /* store the initial parameter types */
  1453.   for (index = 0; index < *recur_parameter_dimension; ++index)
  1454.     recur_parameter_int_real[index] = REAL_TYPE;
  1455.  
  1456.   /* If USER_INITIAL_PARAMETERS_TEMPS=TRUE, then these must be
  1457.      defined for all parameters. */
  1458.   if (RECUR_USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS == TRUE)
  1459.     {
  1460.       if ((RECUR_USER_OPTIONS->user_parameter_temperature =
  1461.        (double *) calloc (*recur_parameter_dimension,
  1462.                   sizeof (double))) == NULL)
  1463.       exit (9);
  1464.       for (index = 0; index < *recur_parameter_dimension; ++index)
  1465.     RECUR_USER_OPTIONS->user_parameter_temperature[index] = 1.0;
  1466.     }
  1467.   /* If USER_INITIAL_COST_TEMP=TRUE, then this must be defined. */
  1468.   if (RECUR_USER_OPTIONS->USER_INITIAL_COST_TEMP == TRUE)
  1469.     {
  1470.       if ((RECUR_USER_OPTIONS->user_cost_temperature =
  1471.        (double *) calloc (1, sizeof (double))) == NULL)
  1472.       exit (9);
  1473.       RECUR_USER_OPTIONS->user_cost_temperature[0] = 5.936648E+09;
  1474.     }
  1475.   /* If DELTA_PARAMETERS=TRUE, then these must be defined for
  1476.      all parameters that will be pseudo-differentiated. */
  1477.   if (RECUR_USER_OPTIONS->DELTA_PARAMETERS == TRUE)
  1478.     {
  1479.       if ((RECUR_USER_OPTIONS->user_delta_parameter =
  1480.        (double *) calloc (*recur_parameter_dimension,
  1481.                   sizeof (double))) == NULL)
  1482.       exit (9);
  1483.       for (index = 0; index < *recur_parameter_dimension; ++index)
  1484.     RECUR_USER_OPTIONS->user_delta_parameter[index] = 0.001;
  1485.     }
  1486.   /* If QUENCH_PARAMETERS=TRUE, then these must be defined for
  1487.      all parameters. */
  1488.   if (RECUR_USER_OPTIONS->QUENCH_PARAMETERS == TRUE)
  1489.     {
  1490.       if ((RECUR_USER_OPTIONS->user_quench_param_scale =
  1491.        (double *) calloc (*recur_parameter_dimension,
  1492.                   sizeof (double))) == NULL)
  1493.       exit (9);
  1494.       for (index = 0; index < *recur_parameter_dimension; ++index)
  1495.     RECUR_USER_OPTIONS->user_quench_param_scale[index] = 1.0;
  1496.     }
  1497.   /* If QUENCH_COST=TRUE, then this must be defined. */
  1498.   if (RECUR_USER_OPTIONS->QUENCH_COST == TRUE)
  1499.     {
  1500.       if ((RECUR_USER_OPTIONS->user_quench_cost_scale =
  1501.        (double *) calloc (1, sizeof (double))) == NULL)
  1502.       exit (9);
  1503.       RECUR_USER_OPTIONS->user_quench_cost_scale[0] = 1.0;
  1504.     }
  1505.   /* If RATIO_TEMPERATURE_SCALES=TRUE, then these must be defined
  1506.      for all parameters. */
  1507.   if (RECUR_USER_OPTIONS->RATIO_TEMPERATURE_SCALES == TRUE)
  1508.     {
  1509.       if ((RECUR_USER_OPTIONS->user_temperature_ratio =
  1510.        (double *) calloc (*recur_parameter_dimension,
  1511.                   sizeof (double))) == NULL)
  1512.       exit (9);
  1513.       for (index = 0; index < *recur_parameter_dimension; ++index)
  1514.     RECUR_USER_OPTIONS->user_temperature_ratio[index] = 1.0;
  1515.     }
  1516.   /* Defines the limit of collection of sampled data by asa */
  1517. #if ASA_SAMPLE
  1518.   /* create memory for bias_generated[] */
  1519.   if ((RECUR_USER_OPTIONS->bias_generated =
  1520.        (double *) calloc (*recur_parameter_dimension, sizeof (double))
  1521.       ) == NULL)
  1522.       exit (9);
  1523.  
  1524. #if ASA_TEMPLATE
  1525.   RECUR_USER_OPTIONS->limit_weights = 1.0E-7;
  1526.   if (RECUR_USER_OPTIONS->QUENCH_COST == TRUE)
  1527.     RECUR_USER_OPTIONS->user_quench_cost_scale[0] = 1.0;
  1528.   if (RECUR_USER_OPTIONS->QUENCH_PARAMETERS == TRUE)
  1529.     for (index = 0; index < *recur_parameter_dimension; ++index)
  1530.       RECUR_USER_OPTIONS->user_quench_param_scale[index] = 1.0;
  1531. #endif
  1532. #endif
  1533.  
  1534. #if ASA_TEMPLATE
  1535. #if ASA_PARALLEL
  1536.   RECUR_USER_OPTIONS->gener_block = 1;
  1537.   RECUR_USER_OPTIONS->gener_block_max = 1;
  1538.   RECUR_USER_OPTIONS->gener_mov_avr = 1;
  1539. #endif
  1540. #endif
  1541. }
  1542.  
  1543. /***********************************************************************
  1544. * double recur_cost_function
  1545. *    This is the users cost function to optimize
  1546. *    (find the minimum).
  1547. *    cost_flag is set to true if the parameter set
  1548. *    does not violates any constraints
  1549. *       recur_parameter_lower_bound and recur_parameter_upper_bound
  1550. *       may be adaptively changed during the search.
  1551. ***********************************************************************/
  1552. #if HAVE_ANSI
  1553. double
  1554. recur_cost_function (double *x,
  1555.              double *recur_parameter_lower_bound,
  1556.              double *recur_parameter_upper_bound,
  1557.              double *recur_cost_tangents,
  1558.              double *recur_cost_curvature,
  1559.              ALLOC_INT * recur_parameter_dimension,
  1560.              int *recur_parameter_int_real,
  1561.              int *recur_cost_flag,
  1562.              int *recur_exit_code,
  1563.              USER_DEFINES * RECUR_USER_OPTIONS)
  1564. #else
  1565. double
  1566. recur_cost_function (x,
  1567.              recur_parameter_lower_bound,
  1568.              recur_parameter_upper_bound,
  1569.              recur_cost_tangents,
  1570.              recur_cost_curvature,
  1571.              recur_parameter_dimension,
  1572.              recur_parameter_int_real,
  1573.              recur_cost_flag,
  1574.              recur_exit_code,
  1575.              RECUR_USER_OPTIONS)
  1576.      double *x;
  1577.      double *recur_parameter_lower_bound;
  1578.      double *recur_parameter_upper_bound;
  1579.      double *recur_cost_tangents;
  1580.      double *recur_cost_curvature;
  1581.      ALLOC_INT *recur_parameter_dimension;
  1582.      int *recur_parameter_int_real;
  1583.      int *recur_cost_flag;
  1584.      int *recur_exit_code;
  1585.      USER_DEFINES *RECUR_USER_OPTIONS;
  1586. #endif
  1587. {
  1588.   double cost_value;
  1589.   static LONG_INT recur_funevals = 0;
  1590.   int *exit_code;
  1591.  
  1592.   double *parameter_lower_bound, *parameter_upper_bound;
  1593.   double *cost_parameters;
  1594.   double *cost_tangents, *cost_curvature;
  1595.   ALLOC_INT *parameter_dimension;
  1596.   int *parameter_int_real;
  1597.   int *cost_flag;
  1598.  
  1599.   USER_DEFINES *USER_OPTIONS;
  1600.  
  1601.   recur_funevals = recur_funevals + 1;
  1602.  
  1603.   if ((USER_OPTIONS =
  1604.        (USER_DEFINES *) calloc (1, sizeof (USER_DEFINES))) == NULL)
  1605.     exit (9);
  1606.  
  1607.   /* USER_OPTIONS->LIMIT_ACCEPTANCES = 10000; */
  1608.   USER_OPTIONS->LIMIT_ACCEPTANCES = 1000;
  1609.   USER_OPTIONS->LIMIT_GENERATED = 99999;
  1610.   USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = 1000;
  1611.   USER_OPTIONS->ACCEPTED_TO_GENERATED_RATIO = 1.0E-6;
  1612.  
  1613.   USER_OPTIONS->COST_PRECISION = 1.0E-18;
  1614.   USER_OPTIONS->MAXIMUM_COST_REPEAT = 2;
  1615.   USER_OPTIONS->NUMBER_COST_SAMPLES = 2;
  1616.  
  1617.   /* USER_OPTIONS->TEMPERATURE_RATIO_SCALE = 1.0E-5; */
  1618.   USER_OPTIONS->TEMPERATURE_RATIO_SCALE = x[0];
  1619.  
  1620.   /* USER_OPTIONS->COST_PARAMETER_SCALE = 1.0; */
  1621.   USER_OPTIONS->COST_PARAMETER_SCALE = x[1];
  1622.  
  1623.   USER_OPTIONS->TEMPERATURE_ANNEAL_SCALE = 100.;
  1624.   USER_OPTIONS->USER_INITIAL_COST_TEMP = FALSE;
  1625.  
  1626.   USER_OPTIONS->INCLUDE_INTEGER_PARAMETERS = FALSE;
  1627.   USER_OPTIONS->USER_INITIAL_PARAMETERS = FALSE;
  1628.   USER_OPTIONS->SEQUENTIAL_PARAMETERS = -1;
  1629.   USER_OPTIONS->INITIAL_PARAMETER_TEMPERATURE = 1.0;
  1630.   USER_OPTIONS->RATIO_TEMPERATURE_SCALES = FALSE;
  1631.   USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS = FALSE;
  1632.  
  1633.   USER_OPTIONS->TESTING_FREQUENCY_MODULUS = 100;
  1634.   USER_OPTIONS->ACTIVATE_REANNEAL = TRUE;
  1635.   USER_OPTIONS->REANNEAL_RESCALE = 10.0;
  1636.   USER_OPTIONS->MAXIMUM_REANNEAL_INDEX = 50000;
  1637.  
  1638.   USER_OPTIONS->DELTA_X = 0.001;
  1639.   USER_OPTIONS->DELTA_PARAMETERS = FALSE;
  1640.   USER_OPTIONS->USER_TANGENTS = FALSE;
  1641.   USER_OPTIONS->CURVATURE_0 = TRUE;
  1642.  
  1643.   USER_OPTIONS->QUENCH_PARAMETERS = FALSE;
  1644.   USER_OPTIONS->QUENCH_COST = FALSE;
  1645.  
  1646.   if ((parameter_dimension =
  1647.        (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL)
  1648.     exit (9);
  1649.   if ((exit_code = (int *) calloc (1, sizeof (int))) == NULL)
  1650.       exit (9);
  1651.   if ((cost_flag = (int *) calloc (1, sizeof (int))) == NULL)
  1652.       exit (9);
  1653.  
  1654. #if ASA_TEST
  1655.   /* set parameter dimension if SELF_OPTIMIZE=TRUE */
  1656.   *parameter_dimension = 4;
  1657.   /* end ASA_TEST */
  1658. #else /* MY_COST */
  1659.   /* set parameter dimension if SELF_OPTIMIZE=TRUE */
  1660. #endif /* MY_COST */
  1661.  
  1662.   if ((parameter_lower_bound =
  1663.        (double *) calloc (*parameter_dimension, sizeof (double))
  1664.       ) == NULL)
  1665.       exit (9);
  1666.   if ((parameter_upper_bound =
  1667.        (double *) calloc (*parameter_dimension, sizeof (double))
  1668.       ) == NULL)
  1669.       exit (9);
  1670.   if ((cost_parameters =
  1671.        (double *) calloc (*parameter_dimension, sizeof (double))
  1672.       ) == NULL)
  1673.       exit (9);
  1674.   if ((parameter_int_real =
  1675.        (int *) calloc (*parameter_dimension, sizeof (int))
  1676.       ) == NULL)
  1677.       exit (9);
  1678.   if ((cost_tangents =
  1679.        (double *) calloc (*parameter_dimension, sizeof (double))
  1680.       ) == NULL)
  1681.       exit (9);
  1682.  
  1683.   if (USER_OPTIONS->CURVATURE_0 == FALSE || USER_OPTIONS->CURVATURE_0 == -1)
  1684.     {
  1685.       if ((cost_curvature =
  1686.        (double *) calloc ((*parameter_dimension) *
  1687.                   (*parameter_dimension),
  1688.                   sizeof (double))) == NULL)
  1689.       exit (9);
  1690.     }
  1691.   else
  1692.     {
  1693.       cost_curvature = (double *) NULL;
  1694.     }
  1695.  
  1696. #if OPTIONAL_DATA
  1697.   /* Set memory to that required for use. */
  1698.   if ((USER_OPTIONS->asa_data =
  1699.        (double *) calloc (2, sizeof (double))) == NULL)
  1700.       exit (9);
  1701.   /* Use asa_data[0] as flag, e.g., if used with SELF_OPTIMIZE. */
  1702.   USER_OPTIONS->asa_data[0] = 1.0;
  1703. #endif
  1704.  
  1705. #if USER_COST_SCHEDULE
  1706.   USER_OPTIONS->cost_schedule = user_cost_schedule;
  1707. #endif
  1708. #if USER_REANNEAL_FUNCTION
  1709.   USER_OPTIONS->reanneal_function = user_reanneal;
  1710. #endif
  1711.  
  1712.   initialize_parameters (cost_parameters,
  1713.              parameter_lower_bound,
  1714.              parameter_upper_bound,
  1715.              cost_tangents,
  1716.              cost_curvature,
  1717.              parameter_dimension,
  1718.              parameter_int_real,
  1719.              USER_OPTIONS);
  1720.  
  1721.   /* It might be a good idea to place a loop around this call,
  1722.      and to average over several values of funevals returned by
  1723.      trajectories of cost_value. */
  1724.  
  1725.   funevals = 0;
  1726.  
  1727. #if USER_ASA_OUT
  1728.   if ((USER_OPTIONS->asa_out_file =
  1729.        (char *) calloc (80, sizeof (char))
  1730.       ) == NULL)
  1731.       exit (9);
  1732. #if ASA_TEMPLATE
  1733.   strcpy (USER_OPTIONS->asa_out_file, "asa_rcur");
  1734. #endif
  1735. #endif
  1736.   cost_value = asa (cost_function,
  1737.             randflt,
  1738.             cost_parameters,
  1739.             parameter_lower_bound,
  1740.             parameter_upper_bound,
  1741.             cost_tangents,
  1742.             cost_curvature,
  1743.             parameter_dimension,
  1744.             parameter_int_real,
  1745.             cost_flag,
  1746.             exit_code,
  1747.             USER_OPTIONS);
  1748.  
  1749.   if (cost_value > .001)
  1750.     {
  1751.       *recur_cost_flag = FALSE;
  1752.     }
  1753.   else
  1754.     {
  1755.       *recur_cost_flag = TRUE;
  1756.     }
  1757.  
  1758. #if FALSE            /* set to 1 to activate FAST EXIT */
  1759.   /* Make a quick exit */
  1760.   if (recur_funevals >= 10)
  1761.     {
  1762.       *recur_cost_flag = FALSE;
  1763.       RECUR_USER_OPTIONS->LIMIT_INVALID_GENERATED_STATES = 0;
  1764.       fprintf (ptr_out, "FAST EXIT set at recur_funevals = 10\n\n");
  1765.     }
  1766. #endif
  1767.  
  1768.   /* print every RECUR_PRINT_FREQUENCY evaluations */
  1769.   if ((RECUR_PRINT_FREQUENCY > 0) &&
  1770.       ((recur_funevals % RECUR_PRINT_FREQUENCY) == 0))
  1771.     {
  1772.       USER_OPTIONS->TEMPERATURE_RATIO_SCALE = x[0];
  1773.       fprintf (ptr_out, "USER_OPTIONS->TEMPERATURE_RATIO_SCALE = %g\n",
  1774.            USER_OPTIONS->TEMPERATURE_RATIO_SCALE);
  1775.       USER_OPTIONS->COST_PARAMETER_SCALE = x[1];
  1776.       fprintf (ptr_out, "USER_OPTIONS->COST_PARAMETER_SCALE = %g\n",
  1777.            USER_OPTIONS->COST_PARAMETER_SCALE);
  1778.     }
  1779. #if TIME_CALC
  1780.   print_time ("", ptr_out);
  1781. #endif
  1782.  
  1783.   fprintf (ptr_out, "recur_funevals = %ld, *recur_cost_flag = %d\n",
  1784.        recur_funevals, *recur_cost_flag);
  1785.   /* cost function = number generated at best cost */
  1786. #if OPTIONAL_DATA
  1787. #if ASA_TEMPLATE
  1788.   funevals = (LONG_INT) (USER_OPTIONS->asa_data[1]);
  1789.   fprintf (ptr_out, "\tbest_funevals = %ld, cost_value = %g\n\n",
  1790.        funevals, cost_value);
  1791.   /* cost function = total number generated during run */
  1792. #endif
  1793. #else /* OPTIONAL_DATA */
  1794.   fprintf (ptr_out, "\tfunevals = %ld, cost_value = %g\n\n",
  1795.        funevals, cost_value);
  1796. #endif
  1797.   fflush (ptr_out);
  1798.  
  1799. #if ASA_SAMPLE
  1800. #if ASA_TEMPLATE
  1801. #if USER_ASA_OUT
  1802.   ptr_asa = fopen (USER_OPTIONS->asa_out_file, "r");
  1803. #else
  1804.   ptr_asa = fopen ("asa_out", "r");
  1805. #endif
  1806.   sample (ptr_out, ptr_asa);
  1807. #endif
  1808. #endif
  1809.  
  1810. #if OPTIONAL_DATA
  1811.   free (USER_OPTIONS->asa_data);
  1812. #endif
  1813. #if USER_ASA_OUT
  1814.   free (USER_OPTIONS->asa_out_file);
  1815. #endif
  1816. #if ASA_SAMPLE
  1817.   free (USER_OPTIONS->bias_generated);
  1818. #endif
  1819.   if (USER_OPTIONS->CURVATURE_0 == FALSE || USER_OPTIONS->CURVATURE_0 == -1)
  1820.     free (cost_curvature);
  1821.   if (USER_OPTIONS->USER_INITIAL_PARAMETERS_TEMPS == TRUE)
  1822.     free (USER_OPTIONS->user_parameter_temperature);
  1823.   if (USER_OPTIONS->USER_INITIAL_COST_TEMP == TRUE)
  1824.     free (USER_OPTIONS->user_cost_temperature);
  1825.   if (USER_OPTIONS->DELTA_PARAMETERS == TRUE)
  1826.     free (USER_OPTIONS->user_delta_parameter);
  1827.   if (USER_OPTIONS->QUENCH_PARAMETERS == TRUE)
  1828.     free (USER_OPTIONS->user_quench_param_scale);
  1829.   if (USER_OPTIONS->QUENCH_COST == TRUE)
  1830.     free (USER_OPTIONS->user_quench_cost_scale);
  1831.   if (USER_OPTIONS->RATIO_TEMPERATURE_SCALES == TRUE)
  1832.     free (USER_OPTIONS->user_temperature_ratio);
  1833.   free (USER_OPTIONS);
  1834.   free (parameter_dimension);
  1835.   free (exit_code);
  1836.   free (cost_flag);
  1837.   free (parameter_lower_bound);
  1838.   free (parameter_upper_bound);
  1839.   free (cost_parameters);
  1840.   free (parameter_int_real);
  1841.   free (cost_tangents);
  1842.  
  1843.   return ((double) funevals);
  1844. }
  1845.  
  1846. #if USER_COST_SCHEDULE
  1847. #if HAVE_ANSI
  1848. double
  1849. recur_user_cost_schedule (double test_temperature,
  1850.               USER_DEFINES * RECUR_USER_OPTIONS)
  1851. #else
  1852. double
  1853. recur_user_cost_schedule (test_temperature,
  1854.               RECUR_USER_OPTIONS)
  1855.      double test_temperature;
  1856.      USER_DEFINES *RECUR_USER_OPTIONS;
  1857. #endif /* HAVE_ANSI */
  1858. {
  1859. #if ASA_TEMPLATE
  1860.   double x;
  1861.  
  1862.   x = test_temperature;
  1863.  
  1864.   return (x);
  1865. #endif
  1866. }
  1867. #endif /* USER_COST_SCHEDULE */
  1868.  
  1869. #if USER_REANNEAL_FUNCTION
  1870. #if HAVE_ANSI
  1871. double
  1872. recur_user_reanneal (double current_temp,
  1873.              double tangent,
  1874.              double max_tangent,
  1875.              USER_DEFINES * RECUR_USER_OPTIONS)
  1876. #else
  1877. double
  1878. recur_user_reanneal (current_temp,
  1879.              tangent,
  1880.              max_tangent,
  1881.              RECUR_USER_OPTIONS)
  1882.      double current_temp;
  1883.      double tangent;
  1884.      double max_tangent;
  1885.      USER_DEFINES *RECUR_USER_OPTIONS;
  1886. #endif /* HAVE_ANSI */
  1887. {
  1888. #if ASA_TEMPLATE
  1889.   double x;
  1890.  
  1891.   x = current_temp * (max_tangent / tangent);
  1892.  
  1893.   return (x);
  1894. #endif
  1895. }
  1896. #endif /* USER_REANNEAL_FUNCTION */
  1897. #endif /* SELF_OPTIMIZE */
  1898.  
  1899. #if ASA_SAMPLE
  1900. #if ASA_TEMPLATE
  1901.  
  1902. #if HAVE_ANSI
  1903. void
  1904. sample (FILE * ptr_out, FILE * ptr_asa)
  1905. #else
  1906. void
  1907. sample (ptr_out, ptr_asa)
  1908.      FILE *ptr_out;
  1909.      FILE *ptr_asa;
  1910. #endif
  1911. {
  1912.   int ind, n_samples, n_accept, index, dim;
  1913.   double cost, cost_temp, bias_accept;
  1914.   double param, temp, bias_gener, aver_weight, range;
  1915.   char ch[80], sample[8];
  1916.  
  1917.   dim = 2;
  1918.   n_samples = 0;
  1919.  
  1920.   fprintf (ptr_out,
  1921.        ":SAMPLE:   n_accept   cost        cost_temp    bias_accept    \
  1922.  aver_weight\n");
  1923.   fprintf (ptr_out,
  1924.        ":SAMPLE:   index      param[]     temp[]       bias_gener[]   \
  1925.  range[]\n");
  1926.   for (;;)
  1927.     {
  1928.       fscanf (ptr_asa, "%s", ch);
  1929.       if (!strcmp (ch, "exit_status"))
  1930.     {
  1931.       break;
  1932.     }
  1933.       if (strcmp (ch, ":SAMPLE#"))
  1934.     {
  1935.       continue;
  1936.     }
  1937.       ++n_samples;
  1938.       fprintf (ptr_out, "%s\n", ch);
  1939.       fflush (ptr_out);
  1940.       fscanf (ptr_asa, "%s%d%lf%lf%lf%lf",
  1941.       sample, &n_accept, &cost, &cost_temp, &bias_accept, &aver_weight);
  1942.       if (strcmp (sample, ":SAMPLE+"))
  1943.     {
  1944.       fprintf (ptr_out, "%s %11d %12.7g %12.7g %12.7g %12.7g\n",
  1945.            sample, n_accept, cost, cost_temp, bias_accept, aver_weight);
  1946.     }
  1947.       else
  1948.     {
  1949.       fprintf (ptr_out, "%s %10d %12.7g %12.7g %12.7g %12.7g\n",
  1950.            sample, n_accept, cost, cost_temp, bias_accept, aver_weight);
  1951.     }
  1952.       for (ind = 0; ind < dim; ++ind)
  1953.     {
  1954.       fscanf (ptr_asa, "%s%d%lf%lf%lf%lf",
  1955.           sample, &index, ¶m, &temp, &bias_gener, &range);
  1956.       fprintf (ptr_out, "%s %11d %12.7g %12.7g %12.7g %12.7g\n",
  1957.            sample, index, param, temp, bias_gener, range);
  1958.     }
  1959.     }
  1960.  
  1961.   fprintf (ptr_out, "\n");
  1962.   fprintf (ptr_out, "n_samples = %d\n", n_samples);
  1963.   fflush (ptr_out);
  1964. }
  1965. #endif /* ASA_TEMPLATE */
  1966. #endif /* ASA_SAMPLE */
  1967.